// #include <iostream>
// #include "ros/ros.h"
// // #include "./devel/include/Person.h"
// #include "publish_info.pb.h"
// #include <fstream>
// #include <sstream>
// #define TEST_COUNT 1000000

// int main(int argc, char **argv)
// {
//     ros::init(argc, argv, "pb_test");
//     ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME,
//                                    ros::console::levels::Debug);
//     ros::NodeHandle n;
//     ros::Publisher pub =
//         n.advertise<pbtest::efftest>("/pb_eff_test", 1000);
//     int count = 0;
//     ros::Rate loop_rate(10);
//     double time_used;
//     pbtest::efftest pb;
//     pb.set_name("aoqingl");
//     pb.set_address("安徽省阜阳市");
//     pb.set_num("123456789");
//     {
//         ros::Time start_time = ros::Time::now();
//         count = TEST_COUNT;
//         //*******************序列化******************
//         std::ofstream output("output.dat", std::ios::binary);
//         // std::ofstream output;
//         while ((count--))
//         {
//             pb.SerializeToOstream(&output);
//         }
//         // 获得时间
//         ros::Time end_time = ros::Time::now();
//         time_used = (end_time - start_time).toSec() * 1000;
//         std::cout << "pb serialization time is :" << time_used << "ms." << std::endl;

//         // std::streampos size = output.tellp();

//         // std::cout << "files size : " << size << std::endl;
//         output.close();
//     }
//     //************************  反序列化   **************
//     {
//         std::ifstream input("output.dat", std::ios::binary);
//         count = TEST_COUNT;
//         ros::Time start_time = ros::Time::now();
//         while ((count--))
//         {
//             pb.ParseFromIstream(&input);
//         }
//         ros::Time end_time = ros::Time::now();
//         time_used = (end_time - start_time).toSec() * 1000;
//         std::cout << "pb deserialization time is :" << time_used << "ms." << std::endl;
//     }
//     return 0;
// }

#if 0
#include <iostream>
#include "ros/ros.h"
#include "publish_info.pb.h" // 假设你的 .proto 文件生成了 pbtest::efftest
#include <chrono> // 用于高精度计时

#define TEST_COUNT 1000000

int main(int argc, char **argv)
{
    ros::init(argc, argv, "pb_test");
    ros::NodeHandle n;

    // 创建 Protobuf 消息实例并填充数据
    pbtest::efftest pb_original;
    pb_original.set_name("aoqingl");
    pb_original.set_address("安徽省阜阳市");
    pb_original.set_num("123456789");

    // --- Protobuf 序列化性能测试 ---
    std::cout << "--- Protobuf Serialization Benchmark ---" << std::endl;
    std::string serialized_data; // 用于存储序列化后的数据，在循环外声明，避免重复分配
    
    // 预热阶段 (可选但推荐): 运行几次，让CPU缓存和分支预测优化
    for(int i = 0; i < 100; ++i) {
        pb_original.SerializeToString(&serialized_data);
    }

    auto start_time_pb_serialize = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < TEST_COUNT; ++i)
    {
        // 每次循环稍微改变数据，防止过度优化导致结果不真实
        pb_original.set_num(std::to_string(i)); 
        pb_original.SerializeToString(&serialized_data);
    }
    auto end_time_pb_serialize = std::chrono::high_resolution_clock::now();
    std::chrono::nanoseconds duration_pb_serialize = 
        std::chrono::duration_cast<std::chrono::nanoseconds>(end_time_pb_serialize - start_time_pb_serialize);

    std::cout << "Protobuf Serialized Size (last message): " << serialized_data.length() << " bytes" << std::endl;
    std::cout << "Protobuf Avg Serialization Time: " << (double)duration_pb_serialize.count() / TEST_COUNT << " ns" << std::endl;
    std::cout << "Protobuf Total Serialization Time: " << duration_pb_serialize.count() / 1e6 << " ms" << std::endl;

    // --- Protobuf 反序列化性能测试 ---
    std::cout << "\n--- Protobuf Deserialization Benchmark ---" << std::endl;
    // 确保我们有数据用于反序列化，这里使用最后一次序列化的数据
    pbtest::efftest pb_deserialized; // 用于存储反序列化后的数据
    
    // 预热阶段 (可选但推荐)
    // for(int i = 0; i < 100; ++i) {
    //     pb_deserialized.ParseFromString(serialized_data);
    // }

    auto start_time_pb_deserialize = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < TEST_COUNT; ++i)
    {
        // 反序列化，每次都从同一个字符串反序列化
        pb_deserialized.ParseFromString(serialized_data);
    }
    auto end_time_pb_deserialize = std::chrono::high_resolution_clock::now();
    std::chrono::nanoseconds duration_pb_deserialize = 
        std::chrono::duration_cast<std::chrono::nanoseconds>(end_time_pb_deserialize - start_time_pb_deserialize);

    std::cout << "Protobuf Avg Deserialization Time: " << (double)duration_pb_deserialize.count() / TEST_COUNT << " ns" << std::endl;
    std::cout << "Protobuf Total Deserialization Time: " << duration_pb_deserialize.count() / 1e6 << " ms" << std::endl;

    // 不要使用 ros::Publisher pub = n.advertise<pbtest::efftest>("/pb_eff_test", 1000);
    // 这与纯序列化/反序列化测试无关。如果你需要测试 ROS Publisher 的性能，那是另一个独立的测试。

    return 0;
}
#endif

#if 0
#include <ros/protobuffer_traits.h>
#include <ros/serialization_protobuffer.h>
#include <ros/ros.h>
#include <chrono> // 用于高精度计时
#include <iostream>
#include <string>

// 包含你的 Protobuf 消息头文件
// 假设你的 .proto 文件生成了类似 'pbtest::efftest' 的类型
#include "publish_info.pb.h"

// 或者如果你想与 ROS 原生消息进行对比：
// #include <my_ros_package/Person.h> // 替换为你的实际 ROS msg 类型

int main(int argc, char** argv) {
    ros::init(argc, argv, "pb_publisher_node");
    ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME,
                                 ros::console::levels::Debug);
    ros::NodeHandle nh;

    // 声明你的发布器（使用你兼容 Protobuf 的 ROS 消息类型）
    // 重要：这假设你有一个 ROS msg 定义来封装你的 Protobuf 消息。
    // 如果你直接发布 Protobuf 序列化的字节，类型会是 std_msgs::ByteMultiArray 或类似。
    // 在这个例子中，我们假设你已经进行了封装，所以 ROS msg 类型是 'pbtest::efftest'
    // （这意味着你有一个与 .proto 文件对应的 .msg 文件，或者自定义了 ROS 序列化器）
    ros::Publisher pub = nh.advertise<pbtest::efftest>("/my_protobuf_topic", 1000); // 队列大小 1000

    ros::Rate loop_rate(5); // 每秒发布一次，用于演示

    // 创建一个 Protobuf 消息实例
    pbtest::efftest proto_msg_to_publish;
    proto_msg_to_publish.set_name("Robotinho");
    proto_msg_to_publish.set_address("火星基地阿尔法");
    proto_msg_to_publish.set_num("1234567890");
    // 如果你的消息包含更复杂的数据，请添加，以使测试更真实
    // for (int i = 0; i < 50; ++i) {
    //     proto_msg_to_publish.add_int_array(i * 10);
    //     proto_msg_to_publish.add_float_array(i * 0.5f);
    // }

    int count = 0;
    while (ros::ok()) {
        proto_msg_to_publish.set_num(std::to_string(count++)); // 稍微改变数据

        // --- 开始计时序列化 ---
        auto start = std::chrono::high_resolution_clock::now();

        // 当你调用 publish() 时，ROS 会在内部执行序列化（对象 -> 字节）
        pub.publish(proto_msg_to_publish);

        auto end = std::chrono::high_resolution_clock::now();
        // --- 结束计时序列化 ---

        std::chrono::nanoseconds duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
        std::cout << "序列化时间 (publish() 调用): " << duration.count() << " 纳秒" << std::endl;

        // 可选地，如果你能访问序列化数据，可以测量其大小
        // 这通常需要深入 ROS 内部或先手动序列化到字符串。
        // 对于纯 Protobuf：
        // std::string temp_serialized_data;
        // proto_msg_to_publish.SerializeToString(&temp_serialized_data);
        // std::cout << "  序列化大小: " << temp_serialized_data.length() << " 字节" << std::endl;

        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}
#endif

#if 0
#include <ros/protobuffer_traits.h>  // 你的 Protobuf ROS 集成所需的头文件
#include <ros/serialization_protobuffer.h> // 你的 Protobuf ROS 集成所需的头文件
#include <ros/ros.h>
#include <chrono> // 用于高精度计时
#include <iostream>
#include <string>
#include <vector> // 用于存储每次的序列化时间

// 包含你的 Protobuf 消息头文件
#include "publish_info.pb.h" // 假设你的 .proto 文件生成了 pbtest::efftest

// 定义测试次数
#define NUM_PUBLICATIONS 1000 // 或者 100，根据你的测试需求设定

int main(int argc, char** argv) {
    ros::init(argc, argv, "pb_publisher_node");
    ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME,
                                   ros::console::levels::Debug);
    ros::NodeHandle nh;

    ros::Publisher pub = nh.advertise<pbtest::efftest>("/my_protobuf_topic", 1000); // 队列大小 1000

    ros::Rate loop_rate(100); // 发布频率，这里是每秒 5 次

    // 创建一个 Protobuf 消息实例并填充初始数据
    pbtest::efftest proto_msg_to_publish;
    proto_msg_to_publish.set_name("Robotinho");
    proto_msg_to_publish.set_address("火星基地阿尔法");
    proto_msg_to_publish.set_num("1234567890");
    // 如果你的消息包含更复杂的数据，请取消注释并添加
    // for (int i = 0; i < 50; ++i) {
    //     proto_msg_to_publish.add_int_array(i * 10);
    //     proto_msg_to_publish.add_float_array(i * 0.5f);
    // }

    std::vector<long long> serialization_times_ns; // 存储每次序列化的纳秒耗时
    serialization_times_ns.reserve(NUM_PUBLICATIONS); // 预分配内存

    int count = 0;
    while (ros::ok() && count < NUM_PUBLICATIONS) {
        proto_msg_to_publish.set_num(std::to_string(count)); // 改变数据以模拟实际场景

        // --- 开始计时序列化 ---
        auto start = std::chrono::high_resolution_clock::now();

        pub.publish(proto_msg_to_publish);

        auto end = std::chrono::high_resolution_clock::now();
        // --- 结束计时序列化 ---

        std::chrono::nanoseconds duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
        serialization_times_ns.push_back(duration.count()); // 记录本次时间

        count++;

        ros::spinOnce();
        loop_rate.sleep();
    }

    // --- 统计并打印结果 ---
    if (!serialization_times_ns.empty()) {
        long long total_duration_ns = 0;
        for (long long time_ns : serialization_times_ns) {
            total_duration_ns += time_ns;
        }

        double average_duration_ns = static_cast<double>(total_duration_ns) / serialization_times_ns.size();
        double average_duration_us = average_duration_ns / 1000.0; // 转换为微秒
        double average_duration_ms = average_duration_us / 1000.0; // 转换为毫秒

        std::cout << "\n--- 序列化性能测试结果 ---" << std::endl;
        std::cout << "总发布次数: " << NUM_PUBLICATIONS << std::endl;
        std::cout << "总序列化耗时: " << total_duration_ns / 1e9 << " 秒 (" << total_duration_ns << " 纳秒)" << std::endl;
        std::cout << "平均每次序列化耗时: " << average_duration_ns << " 纳秒" << std::endl;
        std::cout << "平均每次序列化耗时: " << average_duration_us << " 微秒" << std::endl;
        std::cout << "平均每次序列化耗时: " << average_duration_ms << " 毫秒" << std::endl;

        // 你还可以计算标准差等，如果你需要更详细的统计数据
        // 例如，计算方差和标准差：
        // double sum_sq_diff = 0.0;
        // for (long long time_ns : serialization_times_ns) {
        //     sum_sq_diff += std::pow(time_ns - average_duration_ns, 2);
        // }
        // double std_dev_ns = std::sqrt(sum_sq_diff / serialization_times_ns.size());
        // std::cout << "标准差: " << std_dev_ns << " 纳秒" << std::endl;
    } else {
        std::cout << "没有进行任何发布操作。" << std::endl;
    }

    return 0;
}
#endif